home *** CD-ROM | disk | FTP | other *** search
- #ifndef EXTRAS_THREADS_H
- #include <extras/threads.h>
- #endif
-
- #include <clib/extras/thread_protos.h>
-
- #include <dos.h>
- #include <strings.h>
- //#define DEBUG
- #include <debug.h>
-
- #include <clib/alib_protos.h>
-
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <exec/memory.h>
-
- #include <proto/dos.h>
- #include <proto/exec.h>
- #include <proto/utility.h>
-
- ULONG my_AToI(STRPTR Str);
-
- /* internal use */
- struct InitThread
- {
- struct Task *it_CreaterTask;
- BYTE it_Signal;
- BYTE it_RetVal;
- struct Library *it_ModuleBase;
- struct Thread *it_Thread;
- void __asm (*it_MsgHandler)(register __a0 struct Thread *T,
- register __a1 struct ThreadMessage *Msg);
- };
-
- void SingleMsgPort(struct MsgPort *MP);
- void __asm __saveds ThreadEntry(register __a0 STRPTR Args);
- void __asm __saveds ThreadSubEntry(register __a0 struct InitThread *it,
- register __a6 APTR LibBase);
-
- struct ThreadMessage *InThreadGetMsg(struct Thread *T); // Used by message to get messages for thread
-
- /****** extras.lib/thread_StartThread ******************************************
- *
- * NAME
- * thread_StartThread -- Create a thread.
- *
- * SYNOPSIS
- * Thread thread_StartThread(Tags)
- *
- * struct Thread *thread_StartThread(Tag, ... );
- *
- * FUNCTION
- * Creates and starts a new thread (Process).
- *
- * INPUTS
- * Tags - TagList (on stack)
- * TA_Name - Name of thread, defaults to "Thread".
- * TA_Stack - Stacksize, default 8192.
- * TA_Priority - default -1
- * TA_MsgHandler - Function to handle thread messages.
- * TA_UserData - (APTR)
- *
- * RESULT
- * Pointer to the newly created Thread, or NULL on failure.
- * The Thread stucture is ReadOnly, except for
- * t_Node, UserData and ThreadData
- *
- * NOTES
- * It's suggested that ThreadData be used store local data
- * for the Thread.
- *
- * BUGS
- *
- * SEE ALSO
- *
- ******************************************************************************
- *
- */
-
- struct Thread *thread_StartThread(ULONG Tags, ... )
- {
- struct TagItem *tl;
- struct Thread *thread;
- struct Process *proc=0;
- struct InitThread *init;
- UBYTE initaddr[11];
- BPTR input,output=0;
- BYTE sigbit;
- APTR func;
-
- thread=0;
- tl=(APTR)&Tags;
-
- if(func=(APTR)GetTagData(TA_MsgHandler, 0, tl))
- {
- if(thread=AllocVec(sizeof(*thread),MEMF_CLEAR|MEMF_PUBLIC))
- {
- thread->UserData=(APTR)GetTagData(TA_UserData, 0, tl);
-
- if((sigbit=AllocSignal(-1))!=-1)
- {
- if(init=AllocVec(sizeof(struct InitThread),MEMF_PUBLIC|MEMF_CLEAR))
- {
- init->it_CreaterTask =FindTask(0);
- init->it_Signal =sigbit;
- init->it_ModuleBase =(struct Library *)getreg(REG_A6);
- init->it_Thread =thread;
- init->it_MsgHandler =func;
-
- stci_d(initaddr,(LONG)init);
-
- if(input=Open((STRPTR)"NIL:",MODE_OLDFILE))
- {
- if(output=Open((STRPTR)"NIL:",MODE_NEWFILE))
- {
- // DKP("Creating Proc\n");
-
- if(proc=CreateNewProcTags(NP_Input ,input,
- NP_Output ,output,
- NP_Entry ,ThreadEntry,
- NP_Name ,GetTagData(TA_Name, (ULONG)"Thread", tl),
- NP_StackSize ,GetTagData(TA_Stack, 8192, tl),
- NP_Arguments ,initaddr,
- NP_Priority ,GetTagData(TA_Priority, -1, tl),
- TAG_DONE))
- {
- // DKP("Proc Created - Waiting for Signal it=%8lx a6=%8lx\n",init,init->it_ModuleBase);
- Wait(1<<sigbit);
- // DKP("Signaled RetVal=%ld\n",init->it_RetVal);
- if(!init->it_RetVal)
- proc=0;
- }
- }
- }
- if(!proc)
- {
- if(input)
- Close(input);
- if(output)
- Close(output);
- }
- FreeVec(init);
- }
- FreeSignal(sigbit);
- }
- if(!thread->t_Process)
- {
- FreeVec(thread);
- thread=0;
- }
- }
- }
- // DKP("Leaving CreateInput\n");
- return(thread);
- }
-
- /****** extras.lib/thread_EndThread ******************************************
- *
- * NAME
- * thread_EndThread -- end a thread.
- *
- * SYNOPSIS
- *
- *
- *
- *
- *
- *
- * FUNCTION
- *
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- * Note, this function waits for a reply.
- *
- * BUGS
- *
- * SEE ALSO
- *
- ******************************************************************************
- *
- */
-
-
- void thread_EndThread(struct Thread *Thread, APTR NullForNow)
- {
- struct ThreadMessage diemsg;
- struct MsgPort mp;
-
- if(Thread)
- {
- SingleMsgPort(&mp);
-
- diemsg.tm_Msg.mn_ReplyPort =∓
- diemsg.tm_Msg.mn_Length =sizeof(diemsg);
- diemsg.tm_Command =TMSG_DIE;
-
- if(Thread->t_MsgPort)
- {
- PutMsg(Thread->t_MsgPort,(struct Message *)&diemsg);
- // WaitForReply(&diemsg);
- WaitPort(&mp);
- }
- FreeVec(Thread);
- }
- }
-
- void SingleMsgPort(struct MsgPort *MP)
- {
- MP->mp_Flags=PA_SIGNAL;
- MP->mp_SigBit=SIGF_SINGLE;
- MP->mp_SigTask=FindTask(0);
- NewList(&MP->mp_MsgList);
- }
-
- /* Meat & Potatoes */
-
- void __asm __saveds ThreadEntry(register __a0 STRPTR Args)
- {
- struct InitThread *it;
-
- it=(struct InitThread *)my_AToI(Args);
-
- ThreadSubEntry(it,it->it_ModuleBase);
- }
-
- void __asm __saveds ThreadSubEntry(register __a0 struct InitThread *it,
- register __a6 APTR LibBase)
- {
- struct MsgPort *mp;
- struct Thread *me;
- struct ThreadMessage *msg,*diemsg=0;
- ULONG isig,allsigs,sig;
- BOOL go=TRUE;
- void __asm (*MsgHandler)(register __a0 struct Thread *T,
- register __a1 struct ThreadMessage *Msg,
- register __a6 APTR LibBase);
-
- if(mp=CreateMsgPort())
- {
- isig=1<<mp->mp_SigBit;
-
- me=it->it_Thread;
- it->it_Thread->t_MsgPort = mp;
- it->it_Thread->t_Process = (struct Process *)FindTask(0);
- MsgHandler=it->it_MsgHandler;
-
- it->it_RetVal=1; /* Signal creator */
- Signal(it->it_CreaterTask,1<<it->it_Signal);
-
- it=0; /* don't want to signal again, see below */
-
- allsigs=isig;
- while(go)
- {
- // DKP("Waiting for %8lx\n",allsigs);
-
- // sig=Wait(allsigs);
- sig=Wait(-1);
- // DKP("Signal recieved %8lx\n",sig);
-
- if(sig & isig)
- {
- // DKP("Message signal recieved\n");
- while(msg=(struct ThreadMessage *)GetMsg(mp))
- {
- // DKP("Msg @ 0x%08lx\n",msg);
- switch(msg->tm_Command)
- {
- case TMSG_DIE:
- MsgHandler(me,msg,LibBase);
- diemsg=msg;
- go=0;
- break;
- default:
- MsgHandler(me,msg,LibBase);
- break;
- }
- ReplyMsg((APTR)msg);
- }
- }
-
- if(sig & ~(isig))
- {
- struct TMsg_Signal tms;
-
- tms.TMsg.tm_Msg.mn_Length=sizeof(tms);
- tms.TMsg.tm_Command=TMSG_SIGNAL;
- tms.Signal=sig;
-
- MsgHandler(me,(APTR)&tms,LibBase);
- }
-
- }
- DeleteMsgPort(mp);
- }
-
- if(it)
- {
- it->it_RetVal=0; /* Signal creator */
- Signal(it->it_CreaterTask,1<<it->it_Signal);
- }
-
- if(diemsg)
- ReplyMsg((struct Message *)diemsg);
- }
-
- ULONG my_AToI(STRPTR Str)
- {
- ULONG i=0;
-
- while(*Str>'9' || *Str<'0' && *Str)
- Str++;
-
- while(*Str<='9' && *Str>='0')
- {
- i=(i*10)+((*Str)-'0');
- Str++;
- }
- return(i);
- }
-
- /****** extras.lib/thread_PutTMsg ******************************************
- *
- * NAME
- * thread_PutTMsg -- Send a ThreadMessage to a thread.
- *
- * SYNOPSIS
- *
- *
- *
- *
- *
- *
- * FUNCTION
- *
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- * Note, this function does not wait for a reply.
- *
- * BUGS
- *
- * SEE ALSO
- *
- ******************************************************************************
- *
- */
-
-
- BOOL thread_PutTMsg(struct Thread *Thread, struct ThreadMessage *TM)
- {
- if(Thread)
- {
- if(Thread->t_MsgPort)
- {
- PutMsg(Thread->t_MsgPort,(struct Message *)TM);
- return(1);
- }
- }
- return(0);
- }
-
-
- /****** extras.lib/thread_PutTMsg_TagList ******************************************
- *
- * NAME
- * thread_PutTMsg_TagList -- Send a TagListTMsg to a thread.
- *
- * SYNOPSIS
- *
- *
- *
- *
- *
- *
- * FUNCTION
- *
- *
- * INPUTS
- *
- * RESULT
- *
- * EXAMPLE
- *
- * NOTES
- * Note, this function waits for a reply.
- *
- * BUGS
- *
- * SEE ALSO
- *
- ******************************************************************************
- *
- */
-
-
- ULONG thread_PutTMsg_TagList(struct Thread *Thread, ULONG Command, ULONG Tag, ...)
- {
- struct TMsg_TagList msg;
- struct MsgPort mp;
-
- if(Thread)
- {
- SingleMsgPort(&mp);
-
- msg.tm_Msg.mn_ReplyPort =∓
- msg.tm_Msg.mn_Length =sizeof(msg);
- msg.tm_Command =Command;
- msg.tm_TagList =(APTR)&Tag;
-
- if(Thread->t_MsgPort)
- {
- PutMsg(Thread->t_MsgPort,(struct Message *)&msg);
- // WaitForReply(&diemsg);
-
- while(&msg!=(APTR)GetMsg(&mp))
- {
- WaitPort(&mp);
- }
- return(msg.tm_RetVal);
- }
- }
- return(0);
- }
-